package com.tcheung.service;

import com.tcheung.WordSeg;
import com.tcheung.entity.TFEntity;
import com.tcheung.entity.TFIDFEntity;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;

import java.io.BufferedReader;
import java.io.File;
import java.io.FileReader;
import java.io.IOException;
import java.util.*;

/**
 * QueryService(单例)
 *
 * @author: zhangteng
 * @time: 2014/12/28 16:14
 */
public class QueryService {

    private static QueryService instance = null;

    public static QueryService getInstance(String queryFilePath) {
        if (instance == null) {
            instance = new QueryService(queryFilePath);
        }
        return instance;
    }

    public static QueryService getInstance() {
        return instance;
    }

    Log log = LogFactory.getLog(QueryService.class);

    // query的map
    private Map<Integer, String> queryMap = new LinkedHashMap<Integer, String>();

    // 每个query切词之后的tfmap
    private Map<Integer, List<TFEntity>> queryTFEntityMap = new LinkedHashMap<Integer, List<TFEntity>>();

    // 每个query选取出来的索引词map
    private Map<Integer, HashMap<String, TFIDFEntity>> queryIndexesMap = new LinkedHashMap<Integer, HashMap<String, TFIDFEntity>>();

    // 每个query查询之后得到的结果列表
    private Map<Integer, List<Integer>> queryAnswerMap = new LinkedHashMap<Integer, List<Integer>>();

    private QueryService(String queryFilePath) {
        getQueries(queryFilePath);
        generateIndexes();
    }


    /**
     * 从文件中读取query
     *
     * @param queryFilePath
     */
    private void getQueries(String queryFilePath) {
        File file = new File(queryFilePath);
        BufferedReader reader = null;
        try {
            reader = new BufferedReader(new FileReader(file));
        } catch (Exception e) {
            log.error(e);
        }
        if (reader != null) {
            String query = null;
            int count = 1;
            try {
                while ((query = reader.readLine()) != null) {
                    queryMap.put(count, query);
                    queryTFEntityMap.put(count, WordSeg.segWords(query));
                    count ++;
                }
            } catch (IOException e) {
                log.error(e);
            }
        }
    }

    /**
     * 为所有的query创建索引
     *
     */
    private void generateIndexes() {
        IndexService indexService = IndexService.getInstance();
        for (Map.Entry<Integer, List<TFEntity>> entry : queryTFEntityMap.entrySet()) {
            List<TFEntity> tfEntityList = entry.getValue();
            List<TFIDFEntity> tfidfEntityList = new ArrayList<TFIDFEntity>();
            HashMap<String, TFIDFEntity> indexMap = new HashMap<String, TFIDFEntity>();
            for (TFEntity tfEntity : tfEntityList) {
                Double idf = indexService.getIdfByTerm(tfEntity.getKeyWord());
                // System.out.println(tfEntity.getKeyWord());
                // idf==null,说明这个次不能做为索引词
                // Double idf = Double.valueOf(tfEntity.getTermCount());
                if (idf != null) {
                    // System.out.println(tfEntity.getKeyWord() + "\t" +idf);
                    // TFIDFEntity tfidfEntity = new TFIDFEntity(-1, tfEntity.getKeyWord(), tfEntity.getTf() * idf);
                    TFIDFEntity tfidfEntity = new TFIDFEntity(-1, tfEntity.getKeyWord(), Double.valueOf(tfEntity
                            .getTermCount()));
                    indexMap.put(tfEntity.getKeyWord(), tfidfEntity);
                }
            }
            queryIndexesMap.put(entry.getKey(), indexMap);
        }
    }

    /**
     * 根据queryNum获取索引
     *
     * @param queryNum
     * @return
     */
    public HashMap<String, TFIDFEntity> getQueryIndexesByQueryNum(int queryNum) {
        if (queryIndexesMap.containsKey(queryNum)) {
            return queryIndexesMap.get(queryNum);
        }
        return null;
    }

    /**
     * 获取所有的query
     *
     * @return
     */
    public Map<Integer, String> getQueries() {
        return queryMap;
    }

    /**
     * 获取
     *
     * @param queryNum
     * @param answerList
     */
    public void addAnswer(Integer queryNum, List<Integer> answerList) {
        queryAnswerMap.put(queryNum, answerList);
    }

    public List<Integer> getAnswer(int queryNum) {
        List<Integer> list = Collections.emptyList();
        if (queryAnswerMap.containsKey(queryNum)) {
            list = queryAnswerMap.get(queryNum);
        }
        return list;
    }

    public void setIndexes(int queryNum, HashMap<String, TFIDFEntity> indexes) {
        queryIndexesMap.put(queryNum, indexes);
    }
}
